home *** CD-ROM | disk | FTP | other *** search
- /* #[info: */
- /************************************************************************
- * *
- * #### ####### # ####### ### #### ####### #### *
- * # # # # # # # # # *
- * # # # # # # # # # *
- * ### # ####### # # ### # ### *
- * # # # # # # # # # *
- * # # # # # # # # # *
- * #### # # # # ### #### # #### *
- * *
- * Jan van der Steen *
- * *
- * Centre for Mathematics and Computer Science *
- * Amsterdam, the Netherlands *
- * *
- *----------------------------------------------------------------------*
- * File : statists.c *
- * Purpose : Emit statistics on the game *
- * Version : 1.3 *
- * Modified: 2/17/93 18:22:20 *
- * Author : Jan van der Steen (jansteen@cwi.nl) *
- ************************************************************************/
- /* #]info: */
- /* #[include: */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "gogame.h"
-
- /* #]include: */
- /* #[define: */
-
- #define MAXUSER 1024 /* Maximum length of username */
- #define MAXKIBITZER 256 /* Maximum number of kibitzers */
-
- /* #]define: */
- /* #[typedef: */
-
- typedef struct kib_info {
- char * kib_name;
- int kib_rank;
- int kib_n;
- long kib_tot;
- int kib_avrg;
- } KIBITZER;
-
- /* #]typedef: */
- /* #[extern: */
-
- extern int statout; /* Emit the kibitz stats */
-
- /* #]extern: */
- /* #[prototype: */
-
- #ifdef __STDC__
- # define PROTO(s) s
- #else
- # define PROTO(s) ()
- #endif
-
- static int str2rank PROTO((char *s));
- static char * rank2str PROTO((int rank));
- static int namesort PROTO((KIBITZER *a, KIBITZER *b));
- static int ranksort PROTO((KIBITZER *a, KIBITZER *b));
- static int freqsort PROTO((KIBITZER *a, KIBITZER *b));
- static int bytesort PROTO((KIBITZER *a, KIBITZER *b));
- static int avrgsort PROTO((KIBITZER *a, KIBITZER *b));
-
- #undef PROTO
-
- /* #]prototype: */
- /* #[static: */
-
- static int (*kibsort)() = namesort;
- static KIBITZER kibitzers[MAXKIBITZER] = {0};
-
- /* #]static: */
-
- /* #[kib_list: */
-
- void
- kib_list(mode, label)
- /*
- * List the kibitz info from the database
- */
- int mode;
- char *label;
- {
- KIBITZER *k;
- int i;
-
- switch (mode) {
- case 0: kibsort = namesort; break;
- case 1: kibsort = ranksort; break;
- case 2: kibsort = freqsort; break;
- case 3: kibsort = bytesort; break;
- }
- for (i = 0; i < MAXKIBITZER; i++) {
- k = kibitzers+i;
- if (k->kib_name) k->kib_avrg = (int)((k->kib_tot *100)/k->kib_n);
- }
- qsort(kibitzers, MAXKIBITZER, sizeof(KIBITZER), kibsort);
-
- for (i = 0; i < MAXKIBITZER; i++) {
- k = kibitzers+i;
- if (k->kib_name)
- fprintf(stdout, "%s{%3d}{%-12s}{%-3s}{%3d}{%6ld}{%3d.%02d}\n",
- label,
- i+1,
- k->kib_name,
- rank2str(k->kib_rank),
- k->kib_n,
- k->kib_tot,
- k->kib_avrg/100,
- k->kib_avrg - 100*(k->kib_avrg/100));
- }
- }
-
- /* #]kib_list: */
- /* #[kib_add: */
-
- void
- kib_add(text)
- /*
- * Add kibitz info to the database
- */
- TEXT *text;
- {
- KIBITZER *k;
- TEXT *t;
- int i;
-
- for (t = text; t != (TEXT *) 0; t = t->cc_next) {
- for (i = 0; i < MAXKIBITZER; i++) {
- k = kibitzers+i;
- if (!k->kib_name || !strcmp(k->kib_name, t->cc_name)) {
- /*
- * Either a free slot or we found the user
- */
- if (!k->kib_name) {
- k->kib_name = t->cc_name;
- k->kib_rank = str2rank(t->cc_rank);
- }
- k->kib_tot += strlen(t->cc_text);
- k->kib_n++;
- break;
- }
- }
- if (strcmp(k->kib_name, t->cc_name))
- fprintf(stderr,
- "Internal error: User table full in kib_add()\n");
- }
- }
-
- /* #]kib_add: */
-
- /* #[namesort: */
-
- static int
- namesort(a, b)
- KIBITZER *a;
- KIBITZER *b;
- {
- if (a->kib_name == (char *) 0) return 1000;
- if (b->kib_name == (char *) 0) return -1000;
-
- return strcmp(a->kib_name, b->kib_name);
- }
-
- /* #]namesort: */
- /* #[ranksort: */
-
- static int
- ranksort(a, b)
- KIBITZER *a;
- KIBITZER *b;
- {
- int cmp;
-
- if (a->kib_name == (char *) 0) return 1000;
- if (b->kib_name == (char *) 0) return -1000;
-
- if ((cmp = a->kib_rank - b->kib_rank) != 0) return cmp;
-
- return namesort(a, b);
- }
-
- /* #]ranksort: */
- /* #[freqsort: */
-
- static int
- freqsort(a, b)
- KIBITZER *a;
- KIBITZER *b;
- {
- int cmp;
-
- if (a->kib_name == (char *) 0) return 1000;
- if (b->kib_name == (char *) 0) return -1000;
-
- if ((cmp = b->kib_n - a->kib_n ) != 0) return cmp;
- if ((cmp = (int) (b->kib_tot - a->kib_tot)) != 0) return cmp;
-
- return namesort(a, b);
- }
-
- /* #]freqsort: */
- /* #[bytesort: */
-
- static int
- bytesort(a, b)
- KIBITZER *a;
- KIBITZER *b;
- {
- int cmp;
-
- if (a->kib_name == (char *) 0) return 1000;
- if (b->kib_name == (char *) 0) return -1000;
-
- if ((cmp = (int) (b->kib_tot - a->kib_tot)) != 0) return cmp;
- if ((cmp = b->kib_n - a->kib_n ) != 0) return cmp;
-
- return namesort(a, b);
- }
-
- /* #]bytesort: */
- /* #[avrgsort: */
-
- static int
- avrgsort(a, b)
- KIBITZER *a;
- KIBITZER *b;
- {
- int cmp;
-
- if (a->kib_name == (char *) 0) return 1000;
- if (b->kib_name == (char *) 0) return -1000;
-
- if ((cmp = b->kib_avrg - a->kib_avrg) != 0) return cmp;
- if ((cmp = (int) (b->kib_tot - a->kib_tot)) != 0) return cmp;
- if ((cmp = b->kib_n - a->kib_n ) != 0) return cmp;
-
- return namesort(a, b);
- }
-
- /* #]avrgsort: */
- /* #[str2rank: */
-
- static int
- str2rank(s)
- /*
- * Parse and calculate a rank
- * We distinguish several categories:
- *
- * IGS92 IGS92 -100
- * professional p -10
- * dan d -1
- * kyu k 1
- * NR NR 100
- * ??? ??? 101
- */
- char *s;
- {
- char *t = s;
- int factor = 0;
- int rank = 0;
-
- if (!s || !*s) return -100;
- s += strlen(s)-1;
- if (*s == ' ' || *s == '*') s--;
- switch (*s) {
- case 'p': factor = -10; break;
- case 'd': factor = -1; break;
- case 'k': factor = 1; break;
- /*
- * And now all "funny" rankings
- */
- case 'R': return 100;
- case '?': return 101;
- default : return -100; /* We make them biggest so we notice them */
- }
-
- /*
- * When we arrive here we have to parse a {p,d,k} rank
- */
- while ('0' <= *t && *t <= '9') rank = 10*rank + (*t++ - '0');
-
- return factor * rank;
- }
-
- /* #]str2rank: */
- /* #[rank2str: */
-
- static char *
- rank2str(rank)
- int rank;
- {
- static char s[10];
-
- if (rank == 101) return strcpy(s, " ??");
- if (rank == 100) return strcpy(s, " NR");
- if (rank == -100) return strcpy(s, " XX");
- if (rank <= -10 ) sprintf(s, "%2dp", -rank/10);
- if (rank <= -1 ) sprintf(s, "%2dd", -rank);
- if (rank >= 1 ) sprintf(s, "%2dk", rank);
-
- return s;
- }
-
- /* #]rank2str: */
-
-